import java.util.*;

public class SortedBlocks {

	protected ArrayList <Block> myUDSort;
	protected ArrayList <Block> myLRSort;
	
	public SortedBlocks ( ) {
		this.myUDSort = new ArrayList <Block> ( );
		this.myLRSort = new ArrayList <Block> ( );
	}
	
	public SortedBlocks (SortedBlocks oldSortedBlocks, Block oldBlock, Block newBlock) {
		this.myUDSort = new ArrayList <Block> (oldSortedBlocks.myUDSort);
		this.myLRSort = new ArrayList <Block> (oldSortedBlocks.myLRSort);
		this.replace (oldBlock, newBlock);
	}
	
	public void add (Block block) {
		this.myUDSort.add (this.getIndex (block, this.myUDSort), block);
		this.myLRSort.add (this.getIndex (block, this.myLRSort), block);
	}
	
	public List <Block> getMoveUpBlocks (Block block) {
		return this.myUDSort.subList (0, this.getIndex (block, this.myUDSort));
	}
	
	public List <Block> getMoveDownBlocks (Block block) {
		return this.myUDSort.subList (this.getIndex (block, this.myUDSort), this.myUDSort.size( ));
	}
	
	public List <Block> getMoveLeftBlocks (Block block) {
		return this.myLRSort.subList (0, this.getIndex (block, this.myLRSort));
	}
	
	public List <Block> getMoveRightBlocks (Block block) {
		return this.myLRSort.subList (this.getIndex (block, this.myLRSort), this.myLRSort.size( ));
	}
	
	public void replace (Block oldBlock, Block newBlock) {
		this.myUDSort.remove (this.getIndex (oldBlock, this.myUDSort));
		this.myLRSort.remove (this.getIndex (oldBlock, this.myLRSort));
		this.add (newBlock);
	}
	
	public int getIndex (Block block, ArrayList <Block> list) {
		int low = 0;
		int high = list.size ( ) - 1;
		int mid;
		while (low <= high) {
			mid = (low + high) / 2;
			if (block.equals (list.get (mid)))
				return mid;
			else if (compare (block, list.get (mid), list) < 0)
				high = mid - 1;
			else
				low = mid + 1;
		}
		return low;	
	}
	
	public int compare (Block a, Block b, ArrayList <Block> list) {
		int compareValue;
		if (list == this.myUDSort) {
			compareValue = (a.getCoordinates ( )) [0] - (b.getCoordinates ( )) [0];
			if (compareValue == 0)
				compareValue = (a.getCoordinates ( )) [1] - (b.getCoordinates ( )) [1];
		}else {
			compareValue = (a.getCoordinates ( )) [1] - (b.getCoordinates ( )) [1];
			if (compareValue == 0)
				compareValue = (a.getCoordinates ( )) [0] - (b.getCoordinates ( )) [0];
		}
		return compareValue;
	}
	
	public Iterator <Block> getUDSort ( ) {
		return this.myUDSort.iterator ( );
	}
	public Iterator <Block> getLRSort ( ) {
		return this.myLRSort.iterator ( );
	}
	
	public int size ( ) {
		return myUDSort.size ( );
	}
	
}